/*
 * interrupts.c
 *
 *  Created on: 25.10.2011
 *      Author: Moritz
 */
#include "interrupts.h"
#include "include/AT91SAM7S64.h"





unsigned int AT91F_AIC_ConfigureIt(AT91PS_AIC pAic, // \arg pointer to the AIC registers
		unsigned int irq_id, // \arg interrupt number to initialize
		unsigned int priority, // \arg priority to give to the interrupt
		unsigned int src_type, // \arg activation and sense of activation
		void(*newHandler)()) // \arg address of the interrupt handler
{
	unsigned int oldHandler;
	unsigned int mask;

	oldHandler = pAic->AIC_SVR[irq_id];

	mask = 0x1 << irq_id;
//* Disable the interrupt on the interrupt controller
	pAic->AIC_IDCR = mask;
//* Save the interrupt handler routine pointer and the interrupt priority
	pAic->AIC_SVR[irq_id] = (unsigned int) newHandler;
//* Store the Source Mode Register
	pAic->AIC_SMR[irq_id] = src_type | priority;
//* Clear the interrupt on the interrupt controller
	pAic->AIC_ICCR = mask;

	return oldHandler;
}

void AT91F_AIC_EnableIt(AT91PS_AIC pAic, // \arg pointer to the AIC registers
		unsigned int irq_id) // \arg interrupt number to initialize
{
//* Enable the interrupt on the interrupt controller
	pAic->AIC_IECR = 0x1 << irq_id;
}
#define AT91C_AIC_BRANCH_OPCODE ((void (*) ()) 0xE51FFF20) // ldr, pc, [pc, #-&F20]
unsigned int AT91F_AIC_SetExceptionVector(unsigned int *pVector, // \arg pointer to the AIC registers
		void(*Handler)()) // \arg Interrupt Handler
{
	unsigned int oldVector = *pVector;

	if ((unsigned int) Handler == (unsigned int) AT91C_AIC_BRANCH_OPCODE)
		*pVector = (unsigned int) AT91C_AIC_BRANCH_OPCODE;
	else
		*pVector = (((((unsigned int) Handler) - ((unsigned int) pVector) - 0x8)
				>> 2) & 0x00FFFFFF) | 0xEA000000;

	return oldVector;
}

void irq_register_usart0(void (*callback)(void)) {
	AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_US0, AT91C_AIC_PRIOR_HIGHEST,
			AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, callback);
	AT91C_BASE_US0->US_IER =AT91C_US_RXRDY;// AT91C_US_RXBUFF; //  IRQ enable CPC

	AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_US0);
	// System Interrupt freigeben
	AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SYS);

}

void irq_register_usart1(void (*callback)(void)) {
	AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_US1, AT91C_AIC_PRIOR_HIGHEST,
			AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, callback);
	AT91C_BASE_US1->US_IER =AT91C_US_RXRDY;// AT91C_US_RXBUFF; //  IRQ enable CPC

	AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_US1);
	// System Interrupt freigeben
	AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SYS);

}




